//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#ifndef __BSPUSER_H__
#define __BSPUSER_H__

//UART State Bitmap Values
#define SER_OVERUN      1 << 6 //Received data has been duscarded due to overrun in the device
#define SER_PARITY_ERR  1 << 5 //A partity error has occurred
#define SER_FRAME_ERR   1 << 4 //A framing error has occurred
#define SER_RING_SIGNAL 1 << 3 //State of ring signal detection of the device
#define SER_BREAK       1 << 2 //State of break detection mechanism of the device
#define SER_TX_CARRIER  1 << 1 //State of transmission carrier.This signal corresponds to v.24
                               //signal 106 and RS-232 signal DSR
#define SER_RX_CARRIER  1 << 0 //State of receive carrier detection mechanism of device.This signal
                               //corresponds to v.24 signal 109 and RS-232 signal DCD
//Control Signal Bitmap
#define CARRIER_ACTIVE    (1 << 1)//This signal corresponds to v.24 signal 105 and rs-232 signal RTS
#define CARRIER_DEACTIVE ~(CARRIER_ACTIVE)
#define DTE_PRESENT       (1 << 0)     //Indicates to DCE f DTE is present or not.This signal
#define DTE_NOT_PRESENT  ~(DTE_PRESENT)//corresponds to v.24 signal 108/2 and rs-232 signal DTR

#define RECV_BUFFER_LEN (4096)
#define XMIT_BUFFER_LEN (4096 * 4)
#define BUFFER_NUM 4

/* CDC-ACM Defines and Structures */

#define USB_CDC_SUBCLASS_ACM   2

#define USB_CDC_CTRL_PROTO_NONE    0
#define USB_CDC_CTRL_PROTO_AT      1
#define USB_CDC_CTRL_PROTO_VENDOR  0xff

#define USB_CDC_HEADER     0x00
#define USB_CDC_CALL_MGMT  0x01
#define USB_CDC_ACM        0x02
#define USB_CDC_UNION      0x06

#define USB_CDC_CALL_MGMT_CAP_CALL_MGMT  0x01
#define USB_CDC_CALL_MGMT_CAP_DATA_INTF  0x02

#define USB_CDC_REQ_SET_LINE_CODING  0x20
#define USB_CDC_REQ_GET_LINE_CODING  0x21
#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22

#define USB_CDC_1_STOP_BITS    0
#define USB_CDC_1_5_STOP_BITS  1
#define USB_CDC_2_STOP_BITS    2

#define USB_CDC_NO_PARITY     0
#define USB_CDC_ODD_PARITY    1
#define USB_CDC_EVEN_PARITY   2
#define USB_CDC_MARK_PARITY   3
#define USB_CDC_SPACE_PARITY  4

/* CDC specific */
#define GET_LINE_CODING           0x21
#define SET_LINE_CODING           0x20
#define SET_CONTROL_LINE_STATE    0x22
#define SEND_BREAK                0x23
#define SEND_ENCAPSULATED_COMMAND 0x00
#define GET_ENCAPSULATED_COMMAND  0x01

#define GS_NUM_CONFIGS     1
#define GS_NO_CONFIG_ID    0
#define GS_BULK_CONFIG_ID  1
#define GS_ACM_CONFIG_ID   2

#define GS_MAX_NUM_INTERFACES    2
#define GS_BULK_INTERFACE_ID     0
#define GS_CONTROL_INTERFACE_ID  0
#define GS_DATA_INTERFACE_ID     1

#define GS_DEFAULT_DTE_RATE     115200
#define GS_DEFAULT_DATA_BITS    8
#define GS_DEFAULT_PARITY       USB_CDC_NO_PARITY
#define GS_DEFAULT_CHAR_FORMAT  USB_CDC_1_STOP_BITS

#define LINE_CODE_LEN 7
/* conventional codes for class-specific descriptors */
#define USB_DT_CS_DEVICE     0x21
#define USB_DT_CS_CONFIG     0x22
#define USB_DT_CS_STRING     0x23
#define USB_DT_CS_INTERFACE  0x24
#define USB_DT_CS_ENDPOINT   0x25

//#if defined(_INTEL) || defined(_EVC)
//#define ELR_PACKED
//#pragma pack(push, 1)
//#endif
/* Header Functional Descriptor from CDC spec 5.2.3.1 */
typedef struct ELR_PACKED __usb_cdc_header_desc {
    unsigned char   bLength;
    unsigned char   bDescriptorType;
    unsigned char   bDescriptorSubType;
    unsigned short  bcdCDC;
}usb_cdc_header_desc, *Pusb_cdc_header_desc;

/* Call Management Descriptor from CDC spec 5.2.3.3 */
typedef struct ELR_PACKED __usb_cdc_call_mgmt_desc {
    unsigned char  bLength;
    unsigned char  bDescriptorType;
    unsigned char  bDescriptorSubType;
    unsigned char  bmCapabilities;
    unsigned char  bDataInterface;
}usb_cdc_call_mgmt_desc, *Pusb_cdc_call_mgmt_desc;

/* Abstract Control Management Descriptor from CDC spec 5.2.3.4 */
typedef struct ELR_PACKED __usb_cdc_acm_desc {
    unsigned char  bLength;
    unsigned char  bDescriptorType;
    unsigned char  bDescriptorSubType;
    unsigned char  bmCapabilities;
}usb_cdc_acm_desc, *Pusb_cdc_acm_desc;

/* Union Functional Descriptor from CDC spec 5.2.3.8 */
typedef struct ELR_PACKED __usb_cdc_union_desc {
    unsigned char bLength;
    unsigned char bDescriptorType;
    unsigned char bDescriptorSubType;
    unsigned char bMasterInterface0;
    unsigned char bSlaveInterface0;
    /* ... and there could be other slave interfaces */
}usb_cdc_union_desc, *Pusb_cdc_union_desc;

/* Line Coding Structure from CDC spec 6.2.13 */
typedef struct ELR_PACKED __usb_cdc_line_coding {
    unsigned int dwDTERate;
    unsigned char bCharFormat;
    unsigned char bParityType;
    unsigned char bDataBits;
}usb_cdc_line_coding, *Pusb_cdc_line_coding;

typedef struct ELR_PACKED __gs_acm_fullspeed_function {
    //usb_cdc_header_desc    gs_header_desc;
    usb_cdc_call_mgmt_desc gs_call_mgmt_descriptor;
    usb_cdc_acm_desc       gs_acm_descriptor;
    usb_cdc_union_desc     gs_union_desc;
    endpoint_descriptor    gs_fullspeed_notify_desc;
} acm_function, *Pacm_function;

typedef struct ELR_PACKED __usb_config {
    configuration_descriptor ConfigDesc;
    interface_descriptor     InterfaceDesc_A;
    acm_function             AcmFunction;
    interface_descriptor     InterfaceDesc_B;
    endpoint_descriptor      EndpointDesc_A;
    endpoint_descriptor      EndpointDesc_B;
} usb_config, *Pusb_config;

typedef struct ELR_PACKED __usb_cdc_desc_t {
    device_descriptor cdc_acm_device;
    usb_config cfg_desc;
    string_descriptor cdc_string;
} usb_cdc_desc_t, *p_usb_cdc_desc_t;

typedef struct ELR_PACKED _NOTIFY {
    unsigned char bmRequest, bNotifucation;
    unsigned short wValue, wIndex, wLength, Data;
} SER_NOTIFY, *PSER_NOTIFY;

typedef struct ELR_PACKED __SER_INFO {
 // EP0 Data Xfer info
    int  nXmitLength;  // @field Current EP0 xfer length
    unsigned char*   pXmitData;   // @field Pointer to xmit data for EP0
    int  nXmitIndex;   // @field Index into the current EP0 xmit buffer
    int  nXmitReq;   // @field Requested amount of data on EP0
    SetupPKG dReq;          // @field USB endpoint 0 command
} SER_INFO, *PSER_INFO;

//#if defined(_INTEL) || defined(_EVC)
//#pragma pack(pop)
//#endif

/* in usb_ctl.c (see also descriptor methods at bottom of file) */

// Open the USB client for client and initialize data structures
// to default values, but _do not_ start UDC.
extern void elr_usb_open( unsigned long to );

// Start UDC running
extern int elr_usb_start( void );

// Immediately stop udc, fire off completion routines w/-EINTR
extern int elr_usb_stop( void ) ;

// Disconnect client from usb core
extern int elr_usb_close( void ) ;

extern void elr_connect_hook( int enable );

//endpoint0 functions
void ServiceEP0();
void ProcessEP0InStatus();
void ProcessEP0OutStatus();
void ProcessEP0Setup();
void XmitEP0Data();
int ParseSetup();
int  getCommandEightBytes(void * dataP);
int  getCommand(void * dataP);

//bulk endpoint functions
unsigned int ReceiveData(char *pRxBuf, unsigned int cbSize);
unsigned int TransmitData(char *pTxBuf, unsigned int cbSize);
extern unsigned int bspUDCRead(char *pTxBuffer, unsigned int BufLen);
extern unsigned int bspUDCReadTO(char *pRxBuffer, unsigned int Bufflen, unsigned long TimeOut);
extern unsigned int bspUDCWrite(char *pRxBuffer, unsigned int Bufflen);

#endif //
